package com.circle.rest.modular.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.circle.rest.core.aop.Log;
import com.circle.rest.core.aop.Permission;
import com.circle.rest.core.common.enums.BusinessType;
import com.circle.rest.core.common.model.ErrorResponseData;
import com.circle.rest.core.common.model.SuccessResponseData;
import com.circle.rest.core.common.page.PageInfoBT;
import com.circle.rest.core.exception.ServiceException;
import com.circle.rest.core.util.ToolUtil;
import com.circle.rest.modular.sys.dto.PermissionDto;
import com.circle.rest.modular.sys.model.Menu;
import com.circle.rest.modular.sys.model.Relation;
import com.circle.rest.modular.sys.model.Role;
import com.circle.rest.modular.sys.service.IMenuService;
import com.circle.rest.modular.sys.service.IRelationService;
import com.circle.rest.modular.sys.service.IRoleService;
import com.circle.rest.modular.sys.wrapper.RoleWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 角色信息 前端控制器
 * </p>
 *
 * @author 赵航
 * @since 2019-04-02
 */
@Api(value = "角色信息", tags = {"sys : 角色信息API"})
@RestController
@RequestMapping("/sys/role")
public class RoleController {

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IMenuService menuService;

    @Autowired
    private IRelationService relationService;

    /**
     * 查询角色信息列表
     */
    @ApiOperation("查询角色信息列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "index", value = "起始数据下标", dataType = "int"),
            @ApiImplicitParam(name = "size", value = "数据条数", dataType = "int")
    })
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @Log(title = "查询角色信息列表", businessType = BusinessType.SELECT_LIST)
    @Permission
    public Object list(Integer index, Integer size) {
        Page<Role> page = new Page<>(index == null ? 1 : index, size == null ? 15 : size);
        IPage<Map<String, Object>> mapIPage = roleService.pageMaps(page);
        PageInfoBT<Object> objectPageInfoBT = new PageInfoBT<>(new RoleWrapper(mapIPage).wrap());
        return new SuccessResponseData(objectPageInfoBT);
    }

    /**
     * 添加角色信息
     */
    @ApiOperation("添加角色信息")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @Log(title = "添加角色信息", businessType = BusinessType.INSERT)
    @Permission
    public Object add(Role role) {
        String name = role.getName();
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper = wrapper.eq("name", name);
        List<Role> list = roleService.list(wrapper);
        if (list.size() > 0) {
            throw new ServiceException("已存在同名角色");
        }
        role.setUpdateTime(LocalDateTime.now());
        role.setCreateTime(LocalDateTime.now());
        boolean save = roleService.save(role);
        return new SuccessResponseData(save);
    }

    /**
     * 修改角色信息
     */
    @ApiOperation("修改角色信息")
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @Log(title = "修改角色信息", businessType = BusinessType.UPDATE)
    @Permission
    public Object edit(Role role) {
        if (ToolUtil.isEmpty(role.getId())) {
            return new ErrorResponseData("编号不能为空");
        }
        if (ToolUtil.isEmpty(role.getVersion())) {
            return new ErrorResponseData("版本号不能为空");
        }
        role.setUpdateTime(LocalDateTime.now());
        if (!roleService.updateById(role)) {
            throw new ServiceException("更新失败");
        }
        return new SuccessResponseData();
    }

    /**
     * 删除角色信息
     */
    @ApiOperation("删除角色信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色信息编号", required = true, dataType = "String")
    })
    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    @Log(title = "删除角色信息", businessType = BusinessType.DELETE)
    @Permission
    public Object delete(String id) {
        if (ToolUtil.isEmpty(id)) {
            throw new ServiceException("角色信息编号不能为空");
        }
        Role roleOld = roleService.getById(id);
        if (ToolUtil.isEmpty(roleOld)) {
            throw new ServiceException("角色信息不存在，删除失败");
        }
        if (!roleService.removeById(id)) {
            throw new ServiceException("删除失败");
        }
        return new SuccessResponseData();
    }

    /**
     * 查询角色信息
     */
    @ApiOperation("查询角色信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色信息编号", required = true, dataType = "String")
    })
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    @Log(title = "查询角色信息", businessType = BusinessType.SELECT_ONE)
    @Permission
    public Object detail(String id) {
        if (ToolUtil.isEmpty(id)) {
            throw new ServiceException("角色信息编号不能为空");
        }
        Role role = roleService.getById(id);
        if (ToolUtil.isEmpty(role)) {
            throw new ServiceException("角色信息不存在");
        }
        return new SuccessResponseData(role);
    }

    /**
     * 角色授权
     *
     * @param permissionDto
     * @return
     */
    @ApiOperation("角色授权")
    @RequestMapping(value = "/permission", method = RequestMethod.POST)
    @Log(title = "角色授权", businessType = BusinessType.GRANT)
    @Permission
    @Transactional
    public Object permission(@RequestBody PermissionDto permissionDto) {
        Role role = roleService.getById(permissionDto.getRoleId());
        if (role == null) {
            throw new ServiceException("角色信息不存在");
        }

        QueryWrapper<Relation> wrapper = new QueryWrapper<>();
        wrapper.eq("roleid", role.getId());
        relationService.remove(wrapper);

        List<Relation> relations = new ArrayList<>();
        List<String> menuIds = permissionDto.getMenuIds();
        for (String menuId : menuIds) {
            Relation relation = new Relation();
            relation.setMenuid(menuId);
            relation.setRoleid(role.getId());
            relations.add(relation);
        }
        if (!relationService.saveBatch(relations, relations.size())) {
            throw new ServiceException("授权失败");
        }
        return new SuccessResponseData();
    }

    /**
     * 授权角色所有权限
     *
     * @param roleId
     * @return
     */
    @ApiOperation("授权角色所有权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色信息编号", required = true, dataType = "String")
    })
    @RequestMapping(value = "/permissionAll", method = RequestMethod.GET)
    @Log(title = "授权角色所有权限", businessType = BusinessType.GRANT)
    @Permission
    @Transactional
    public Object permissionAllMenu(String roleId) {
        Role role = roleService.getById(roleId);
        if (role == null) {
            throw new ServiceException("角色信息不存在");
        }

        QueryWrapper<Relation> wrapper = new QueryWrapper<>();
        wrapper.eq("roleid", role.getId());
        relationService.remove(wrapper);

        List<Menu> menus = menuService.list();
        List<Relation> relations = new ArrayList<>();
        for (Menu menu : menus) {
            Relation relation = new Relation();
            relation.setMenuid(menu.getId());
            relation.setRoleid(role.getId());
            relations.add(relation);
        }
        if (relationService.saveBatch(relations, relations.size())) {
            return new SuccessResponseData("授权成功");
        }
        throw new ServiceException("授权失败");
    }
}
